package com.yuanxiao.common.core.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.MappingJsonFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class JsonUtils {

    static Logger logger= LoggerFactory.getLogger(JsonUtils.class);

    public static String toJson(Object object) {
        MappingJsonFactory f = new MappingJsonFactory();
        StringWriter sw = new StringWriter();
        try {
            JsonGenerator generator = f.createGenerator(sw);
            generator.writeObject(object);
            generator.close();
        } catch (Exception e) {
            logger.error("error",e);
            return "";
        }
        return sw.toString();
    }

    /**
     * java类转为json字符串
     * @param object
     * @return
     */
    public static final String toJsonExcludeNull(Object object){
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        StringWriter sw = new StringWriter();
        try {
            mapper.writeValue(sw,object);
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
        return sw.toString();
    }

    public static String toJsonExcEmpty(Object object) {
        MappingJsonFactory f = new MappingJsonFactory();
        ObjectMapper mapper=f.getCodec();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        StringWriter sw = new StringWriter();
        try {
            JsonGenerator generator = f.createGenerator(sw);
            generator.writeObject(object);
            generator.close();

        } catch (Exception e) {
            logger.error("error",e);
            return "";
        }
        return sw.toString();

    }

    public static String toJsonExcNull(Object object) {
        MappingJsonFactory f = new MappingJsonFactory();
        ObjectMapper mapper=f.getCodec();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        StringWriter sw = new StringWriter();
        try {
            JsonGenerator generator = f.createGenerator(sw);
            generator.writeObject(object);
            generator.close();

        } catch (Exception e) {
            logger.error("error",e);
            return "";
        }
        return sw.toString();

    }

    public static <T> T parseJsonStrict(String jsonString, Class<T> c){

        if (StringUtils.isBlank(jsonString)) {
            return null;
        }

        MappingJsonFactory f = new MappingJsonFactory();
        try {
            JsonParser parser = f.createParser(jsonString);
             return parser.readValueAs(c);
        } catch (Exception e) {
            logger.error("Error",e);
            return null;
        }

    }

    public static <T> T parseJson(String jsonString, Class<T> c){
        if (StringUtils.isBlank(jsonString)) {
            return null;
        }

        MappingJsonFactory f = new MappingJsonFactory();
        ObjectMapper mapper=f.getCodec();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        try {
            JsonParser parser = f.createParser(jsonString);
            return parser.readValueAs(c);
        } catch (Exception e) {
            logger.error("Error",e);
            return null;
        }
    }

    /**
     * 将object(linkedHashMap)转化为pojo
     * @param o
     * @param c
     * @param <T>
     * @return
     */
    public static <T> T objectToPojo(Object o, Class<T> c){
        MappingJsonFactory f = new MappingJsonFactory();
        StringWriter sw = new StringWriter();
        try {
            JsonGenerator generator = f.createGenerator(sw);
            generator.writeObject(o);
            generator.close();
        } catch (Exception e) {
            logger.error("error",e);
        }
        String jsonString = sw.toString();

        if (StringUtils.isBlank(sw.toString())) {
            return null;
        }
        try {
            JsonParser parser = f.createParser(jsonString);
            return parser.readValueAs(c);
        } catch (Exception e) {
            logger.error("Error",e);
            return null;
        }
    }

    /**
     * 将object(linkedHashMap)转化为pojo
     * @param o
     * @param c
     * @param <T>
     * @return
     */
    public static <T> T myObjectToPojo(Object o, Class<T> c){
        MappingJsonFactory f = new MappingJsonFactory();
        StringWriter sw = new StringWriter();
        try {
            JsonGenerator generator = f.createGenerator(sw);
            generator.writeObject(o);
            generator.close();
        } catch (Exception e) {
            logger.error("error",e);
        }
        String jsonString = sw.toString();

        return JsonToPojo(jsonString,c);
    }

    /**
     * 将json转化为pojo
     * @param jsonStr
     * @param obj
     * @param <T>
     * @return
     */
    public static <T> T JsonToPojo(String jsonStr, Class<T> obj){
        List<T> list = new ArrayList<>();
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        try {
            JavaType javaType = mapper.getTypeFactory()
                    .constructParametricType(ArrayList.class, obj);
            list = mapper.readValue(jsonStr, javaType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(list.size()>0){
            return list.get(0);
        }else {
            return null;
        }
    }

    /**
     * 将json转化为List
     * @param jsonStr
     * @param obj
     * @param <T>
     * @return
     */
    public static <T> List<T> JsonToList(String jsonStr, Class<T> obj){
        List<T> list = new ArrayList<>();
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        try {
            JavaType javaType = mapper.getTypeFactory()
                    .constructParametricType(ArrayList.class, obj);
            list = mapper.readValue(jsonStr, javaType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    public static <T> List<T> JsonToListMap(String jsonStr){
        List<T> list = new ArrayList<>();
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        try {
            list = (List<T>) mapper.readValue(jsonStr, new TypeReference<List<Map>>() {});
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
    /**
     * 将object(List<linkedHashMap>)转化为List
     * @param o
     * @param obj
     * @param <T>
     * @return
     */
    public static <T> List<T> objectToList(Object o, Class<T> obj){
        List<T> list = new ArrayList<>();
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        String jsonStr = toJson(o);
        try {
            JavaType javaType = mapper.getTypeFactory()
                    .constructParametricType(ArrayList.class, obj);
            list = mapper.readValue(jsonStr, javaType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }


    public static <T> T parseJson(String jsonString, TypeReference<T> typRef) {
        if(StringUtils.isBlank(jsonString)) {
            return null;
        } else {
            MappingJsonFactory f = new MappingJsonFactory();
            ObjectMapper mapper = f.getCodec();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            try {
                JsonParser e = f.createParser(jsonString);
                return e.readValueAs(typRef);
            } catch (Exception var5) {
                logger.error("Error", var5);
                return null;
            }
        }
    }

    /**
     * 校验字符串是否是json
     * @param jsonInString
     * @return false:不是合法json
     */
    public static boolean isJSONValid(String jsonInString ) {
        try {
            final ObjectMapper mapper = new ObjectMapper();
            mapper.readTree(jsonInString);
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    public static String stringToJson(String s) {
        return s.replaceAll("\\\\", "").replaceAll("\"\\{","\\{").replaceAll("\\}\"","\\}").replaceAll("&quot;","\"");
    }

}